home *** CD-ROM | disk | FTP | other *** search
- /* ProcessPDCommands.c */
- /*
- * ProcessPDCommands.c
- * Copyright © 1992-93 Apple Computer Inc. All Rights Reserved.
- *
- *
- * ProcessPDCommands is the mainline for all complex requests
- * -- these can potentially initiate I/O. If the request completes
- * without causing additional I/O (for example, if a parameter error
- * prevents continuation), it calls DirRequestCompletion to dequeue
- * the next request. Otherwise, the asychronous I/O request calls
- * DirRequestCompletion when it is done.
- *
- * ProcessPDCommands uses a private parameter block for its
- * I/O requests. If the request was synchronous, ProcessPDCommands
- * makes synchronous requests. If the request was asychronous,
- * ProcessPDCommands makes asychronous requests, using a private
- * completion routine.
- *
- * This private completion routine copies the status code to the
- * user's parameter block and calls the user's completion routine,
- * if any. When the user's completion routine returns, the private
- * completion routine examines the request queue. If it is not empty,
- * it re-calls ProcessPDCommands to handle the next request.
- *
- * The guts of the code are specific to this particular CSAM.
- *
- * Edit History
- * 8-Jul-1993 MM Errors from GetRefNumFromRLI (shouldn't happen) now call I/O
- * I/O Completion. Also, added DirFindValue and DirFindRecord
- * skeletons. Moved GetRefNumFromRLI audit inside the call
- */
- #include "DTSSampleCSAM.h"
-
- void DirRequestCompletion(
- DirParamBlockPtr myPB
- );
-
-
- static pascal Boolean MyForEachRecord(
- DirParamBlock *userPB,
- const DirEnumSpec *enumSpec
- )
- {
-
- OSErr status;
- Boolean stopNow;
- long saveA5;
- char buffer[kMinPackedRLISize + kDirectoryNameMaxBytes];
- PackedRLIPtr prli;
-
- prli = (PackedRLIPtr) buffer;
- stopNow = FALSE;
- if (userPB->findRecordParsePB.forEachRecordFunc != NULL) {
- status = OCEPackRLIParts(
- userPB->findRecordParsePB.directoryName,
- &userPB->findRecordParsePB.discriminator,
- kRootDNodeNumber,
- NULL,
- 0,
- prli,
- kMinPackedRLISize
- + kDirectoryNameMaxBytes
- - sizeof(ProtoPackedRLI)
- );
- saveA5 = SetA5(userPB->header.saveA5);
- stopNow = userPB->findRecordParsePB.forEachRecordFunc(
- userPB->header.clientData,
- enumSpec,
- prli
- );
- SetA5(saveA5);
- }
- return (stopNow);
- }
-
- void
- ProcessPDCommands(
- register DTSSampleCSAMInfoPtr infoPtr,
- register DirParamBlockPtr pb,
- Boolean async
- )
- {
- register OSErr status;
- char buffer[kMinPackedRLISize + kDirectoryNameMaxBytes];
- PackedRLIPtr prli;
- #define MYPB (INFO.dirParamBlock)
- #define MYENUMSPEC (INFO.enumSpec)
-
- prli = (PackedRLIPtr) buffer;
- /*
- * Note: we have to be careful not to touch STATUS (pb->header.ioResult)
- * until the request completes as the user may be bit-spinning on
- * STATUS == ioBusy).
- *
- * Copy the user parameter block into our private parameter block -- so we
- * can use our private ioCompletion and enumeration routines.
- */
- BlockMove(&PARAM, &MYPB, sizeof PARAM);
- status = MemError();
- if (status != noErr) /* This can't happen */
- goto exit;
- MYPB.header.ioCompletion =
- (async) ? (ProcPtr) DirRequestCompletion : NULL;
- MYPB.header.clientData = (long) pb;
- MYPB.header.dsRefNum = 0;
- MYPB.header.ioResult = ioBusy;
- switch (MYPB.header.reqCode) {
- case kDirEnumerateParse:
- LogText('PCmd', "\pkDirEnumerateParse");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.enumerateParsePB.aRLI,
- &MYPB.header.dsRefNum
- );
- LogStatus('PCmd', status, "\pGetRefNumFromRLI");
- if (status != noErr)
- goto fail;
- else {
- MYPB.enumerateParsePB.eachEnumSpec = MyForEachEnumSpec;
- status = DirEnumerateParse(&MYPB, async);
- LogStatus('PCmd', status, "\pDirEnumerateParse");
- }
- break;
- case kDirFindRecordParse:
- LogText('PCmd', "\pkDirFindRecordParse");
- OCEPackRLIParts(
- pb->findRecordParsePB.directoryName,
- &pb->findRecordParsePB.discriminator,
- kRootDNodeNumber,
- NULL,
- 0,
- prli,
- kMinPackedRLISize + kDirectoryNameMaxBytes - sizeof(ProtoPackedRLI)
- );
- status = GetRefNumFromRLI(
- infoPtr,
- prli,
- &MYPB.header.dsRefNum
- );
- LogStatus('PCmd', status, "\pGetRefNumFromRLI");
- if (status != noErr)
- goto fail;
- else {
- MYPB.enumerateParsePB.eachEnumSpec =
- (ForEachDirEnumSpec) MyForEachRecord;
- MYPB.enumerateParsePB.getBuffer = pb->findRecordParsePB.getBuffer;
- MYPB.enumerateParsePB.getBufferSize = pb->findRecordParsePB.getBufferSize;
- status = DirEnumerateParse(&MYPB, async);
- LogStatus('PCmd', status, "\pDirEnumerateParse");
- }
- break;
- case kDirLookupParse:
- LogText('PCmd', "\pkDirLookupParse");
- status = GetRefNumFromRLI(
- infoPtr,
- (*MYPB.lookupParsePB.aRecordList)->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- MYPB.lookupParsePB.eachRecordID = MyForEachLookupRecordID;
- MYPB.lookupParsePB.eachAttrType = MyForEachAttrTypeLookup;
- MYPB.lookupParsePB.eachAttrValue = MyForEachAttrValue;
- status = DirLookupParse(&MYPB, async);
- LogStatus('PCmd', status, "\pDirLookupParse");
- }
- break;
- case kDirEnumerateAttributeTypesParse:
- LogText('PCmd',"\pkDirEnumerateAttributeTypesParse");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.enumerateAttributeTypesParsePB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- MYPB.enumerateAttributeTypesParsePB.eachAttrType =
- MyForEachAttrType;
- status = DirEnumerateAttributeTypesParse(&MYPB, async);
- LogStatus('PCmd', status, "\pDirEnumerateAttributeTypesParse");
- }
- break;
- case kDirEnumeratePseudonymParse:
- LogText('PCmd', "\pkDirEnumeratePseudonumParse");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.enumeratePseudonymParsePB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- MYPB.lookupParsePB.eachRecordID = MyForEachRecordID;
- status = DirEnumeratePseudonymParse(&MYPB, async);
- LogStatus('PCmd', status, "\pDirEnumeratePseudonymParse");
- }
- break;
- case kDirAddRecord:
- LogText('PCmd', "\pkDirAddRecord");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.addRecordPB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirAddRecord(&MYPB, async);
- LogStatus('PCmd', status, "\pDirAddRecord");
- }
- break;
- case kDirDeleteRecord:
- LogText('PCmd', "\pkDirDeleteRecord");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.deleteRecordPB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirDeleteRecord(&MYPB, async);
- LogStatus('PCmd', status, "\pDirDeleteRecord");
- }
- break;
- case kDirAddAttributeValue:
- LogText('PCmd', "\pkDirAddAttributeValue");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.addAttributeValuePB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirAddAttributeValue(&MYPB, async);
- LogStatus('PCmd', status, "\pDirAddAttributeValue");
- }
- break;
- case kDirDeleteAttributeValue:
- LogText('PCmd', "\pkDirDeleteAttributeValue");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.deleteAttributeValuePB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirDeleteAttributeValue(&MYPB, async);
- LogStatus('PCmd', status, "\pDirDeleteAttributeValue");
- }
- break;
- case kDirChangeAttributeValue:
- LogText('PCmd', "\pkDirChangeAttributeValue");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.changeAttributeValuePB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirChangeAttributeValue(&MYPB, async);
- LogStatus('PCmd', status, "\pDirChangeAttributeValue");
- }
- break;
- case kDirVerifyAttributeValue:
- LogText('PCmd', "\pkDirVerifyAttributeValue");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.verifyAttributeValuePB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirVerifyAttributeValue(&MYPB, async);
- LogStatus('PCmd', status, "\pDirVerifyAttributeValue");
- }
- break;
- case kDirAddPseudonym:
- LogText('PCmd', "\pkDirAddPseudonym");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.addPseudonymPB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirAddPseudonym(&MYPB, async);
- LogStatus('PCmd', status, "\pDirAddPseudonym");
- }
- break;
- case kDirDeletePseudonym:
- LogText('PCmd', "\pkDirDeletePseudonym");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.deletePseudonymPB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- DirDeletePseudonym(&MYPB, async);
- LogStatus('PCmd', status, "\pDirDeletePseudonym");
- }
- break;
- case kDirEnumerateGet:
- LogText('PCmd', "\pkDirEnumerateGet");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.enumerateGetPB.aRLI,
- &MYPB.header.dsRefNum);
- if (status != noErr)
- goto fail;
- else {
- status = DirEnumerateGet(&MYPB, async);
- LogStatus('PCmd', status, "\pDirEnumerateGet");
- }
- break;
- case kDirFindRecordGet:
- LogText('PCmd', "\pkDirFindRecordGet");
- OCEPackRLIParts(
- pb->findRecordParsePB.directoryName,
- &pb->findRecordParsePB.discriminator,
- kRootDNodeNumber,
- NULL,
- 0,
- prli,
- kMinPackedRLISize + kDirectoryNameMaxBytes - sizeof(ProtoPackedRLI)
- );
- status = GetRefNumFromRLI(
- infoPtr,
- prli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- if (pb->findRecordGetPB.startingPoint == NULL)
- MYPB.enumerateGetPB.startingPoint = NULL;
- else {
- MYENUMSPEC.enumFlag = kEnumDistinguishedNameMask;
- MYENUMSPEC.indexRatio = 0;
- BlockMove(
- &pb->findRecordGetPB.startingPoint->local,
- &MYENUMSPEC.u.recordIdentifier,
- sizeof(LocalRecordID)
- );
- MYPB.enumerateGetPB.startingPoint = &MYENUMSPEC;
- }
- MYPB.enumerateGetPB.aRLI = NULL;
- MYPB.enumerateGetPB.sortBy = kSortByName;
- MYPB.enumerateGetPB.sortDirection = kSortForwards;
- MYPB.enumerateGetPB.nameMatchString = pb->findRecordGetPB.nameMatchString;
- MYPB.enumerateGetPB.typesList = pb->findRecordGetPB.typesList;
- MYPB.enumerateGetPB.typeCount = pb->findRecordGetPB.typeCount;
- MYPB.enumerateGetPB.enumFlags = kEnumDistinguishedNameMask + kEnumAliasMask + kEnumPseudonymMask;
- MYPB.enumerateGetPB.includeStartingPoint = false;
- MYPB.enumerateGetPB.matchNameHow = pb->findRecordGetPB.matchNameHow;
- MYPB.enumerateGetPB.matchTypeHow = pb->findRecordGetPB.matchTypeHow;
- MYPB.enumerateGetPB.getBuffer = pb->findRecordGetPB.getBuffer;
- MYPB.enumerateGetPB.getBufferSize = pb->findRecordGetPB.getBufferSize;
- status = DirEnumerateGet(&MYPB, async);
- LogStatus('PCmd', status, "\pDirEnumerateGet");
- }
- break;
- case kDirEnumerateAttributeTypesGet:
- LogText('PCmd', "\pkDirEnumerateAttributeTypesGet");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.enumerateAttributeTypesGetPB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirEnumerateAttributeTypesGet(&MYPB, async);
- LogStatus('PCmd', status, "\pDirEnumerateAttributeTypesGet");
- }
- break;
- case kDirEnumeratePseudonymGet:
- LogText('PCmd', "\pkDirEnumeratePseudonymGet");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.enumeratePseudonymGetPB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirEnumeratePseudonymGet(&MYPB, async);
- LogStatus('PCmd', status, "\pDirEnumeratePseudonymGet");
- }
- break;
- case kDirGetNameAndType:
- LogText('PCmd', "\pkDirGetNameAndType");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.getNameAndTypePB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirGetNameAndType(&MYPB, async);
- LogStatus('PCmd', status, "\pDirGetNameAndType");
- }
- break;
- case kDirSetNameAndType:
- LogText('PCmd', "\pkDirSetNameAndType");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.setNameAndTypePB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirSetNameAndType(&MYPB, async);
- LogStatus('PCmd', status, "\pDirSetNameAndType");
- }
- break;
- case kDirGetRecordMetaInfo:
- LogText('PCmd', "\pkGetRecordMetaInfo");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.getRecordMetaInfoPB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirGetRecordMetaInfo(&MYPB, async);
- LogStatus('PCmd', status, "\pDirGetRecordMetaInfo");
- }
- break;
- case kDirLookupGet:
- LogText('PCmd', "\pkDirLookupGet");
- status = GetRefNumFromRLI(
- infoPtr,
- (*MYPB.lookupGetPB.aRecordList)->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirLookupGet(&MYPB, async);
- LogStatus('PCmd', status, "\pDirLookupGet");
- }
- break;
- case kDirGetDNodeMetaInfo:
- LogText('PCmd', "\pkDirGetDNodeMetaInfo");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.getDNodeMetaInfoPB.pRLI,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirGetDNodeMetaInfo(&MYPB, async);
- LogStatus('PCmd', status, "\pDirGetDNodeMetaInfo");
- }
- break;
- case kDirAddAlias:
- LogText('PCmd', "\pkDirGetRefNumFromRLI");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.addAliasPB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirAddAlias(&MYPB, async);
- LogStatus('PCmd', status, "\pDirAddAlias");
- }
- break;
- case kDirDeleteAttributeType:
- LogText('PCmd', "\pkDirDeleteAttributeType");
- status = GetRefNumFromRLI(
- infoPtr,
- MYPB.deleteAttributeTypePB.aRecord->rli,
- &MYPB.header.dsRefNum
- );
- if (status != noErr)
- goto fail;
- else {
- status = DirDeleteAttributeType(&MYPB, async);
- LogStatus('PCmd', status, "\pDirDeleteAttributeType");
- }
- break;
- case kDirFindValue:
- LogText('PCmd', "\pkDirFindValue");
- {
- status = controlErr; //** TBS: Code not written yet
- goto fail;
- }
- break;
- default:
- /*
- * Error: incorrect request code.
- */
- #if DEBUG_LOG
- AuditStatusLocation(INFO.auditPtr, 'Cmd?', MYPB.header.reqCode);
- #endif
- status = controlErr;
- /*
- * goto fail with errors.
- */
- fail: MYPB.header.ioResult = status;
- if (async)
- DirRequestCompletion(&MYPB);
- break;
- }
- exit: STATUS = status;
- LogStatus('PSts', STATUS, "\pProcessPDCommands exit");
- #undef MYPB
- }
-
- /*
- * This is the completion routine called by the Dir... routines when
- * one of the above requests complete. It does the following:
- *
- * 1. remove the user parameter block from the request queue.
- * 2. call the user completion routine, if any.
- * 3. if there is still something in the request queue, call
- * ProcessPDCommands to start working on it. Note that
- * this call "must" be asychronous. The only way to have
- * several things in the request queue is for all of them
- * (except, possibly, the first) to be asychronous.
- */
- void
- DirRequestCompletion(
- DirParamBlockPtr myPB
- )
- {
- DirParamBlockPtr userPB;
- DirParamBlockPtr nextPB;
- #define infoPtr ((DTSSampleCSAMInfoPtr) myPB)
-
- #if DEBUG_LOG
- if (myPB->header.ioResult != noErr)
- AuditStatusLocation(INFO.auditPtr, 'DiRC', myPB->header.ioResult);
- #endif
- userPB = (DirParamBlockPtr) myPB->header.clientData;
- if (myPB->header.ioResult == ioBusy || userPB == NULL)
- AuditStatusLocation(INFO.auditPtr, 'DiRC', myPB->header.ioResult);
- else {
- /*
- * Copy completion code to user function and call the user's completion
- * routine (if any). The queue management duplicates DequeueFirst() logic.
- */
- userPB->header.ioResult = myPB->header.ioResult;
- CallCompletion((ParmBlkPtr) userPB);
- nextPB = (DirParamBlockPtr) INFO.requestQueueHdr.qHead;
- if (nextPB != NULL) {
- if (Dequeue((QElemPtr) nextPB, &INFO.requestQueueHdr) == noErr) {
- ProcessPDCommands(infoPtr, nextPB, TRUE);
- }
- }
- }
- }
-